import React, { Component, useState } from "react";
import "./index.css";

export default function Myswiper(props) {
  const { imageList1, showButton, setshowButton, setDesc, Desc } = props;
  // 用于管理文案是否显示
  // const [Desc, setDesc] = useState(false);
  // 用于管理按钮是否显示
  // const [showButton, setshowButton] = useState(false);
  // 计时器
  const timer = React.useRef();

  const imageList = React.useMemo(() => {
    // console.log(imageList1.length);
    if (imageList1.length >= 5) {
      return imageList1;
    }

    function listLength(list) {
      if (list.length >= 5) {
        return list;
      } else {
        return listLength([...list, ...imageList1]);
      }
    }
    return listLength(imageList1);
  }, []);

  // 因为使用计时器形成一个闭包 ，导致在计算图片定位时无法获
  // 取到最新的position 信息，所以这里使用ref 来存储posiion的状态
  // 除非手动去改变 否则ref的对象始终是我们写入的对象，这个对象
  // 无法被闭包等缓存，每次获取 都是直接在ref 中取值，所以可以用它
  // 来解决我们的position变量缓存的问题
  const positions = React.useRef({
    length: imageList.length,
    first: imageList.length - 2, //第一张图片
    prev: imageList.length - 1, //前一张图片
    curr: 0, //当前显示的图片
    next: 1, //当前显示的下一张图片
    last: 2, //最后一张图片
  });

  /**
   * 计算当前图片的位置
   * 不依赖外界的状态 不影响外界的状态，他返回的结果只受参数变化的影响 这种函数被称为纯函数
   */
  const calcPosition = React.useCallback((curr, isReduce) => {
    if (isReduce) {
      return curr <= 0 ? positions.current.length - 1 : curr - 1;
      // return curr - 1 < 0 ? positions.current.length - 1 : curr - 1;
    } else {
      return curr + 1 >= positions.current.length ? 0 : curr + 1;
    }
  }, []);

  /***
   * 切换图片 修改图片的位置
   * 因为我们使用了useCallback ，
   * 所以需要监听positionsn的变化，
   * 避免执行dispatch时positions的内容无法更新
   */
  const changeImagePosition = React.useCallback((isReduce) => {
    const { curr, prev, next, first, last } = positions.current;
    // 默认隐藏文案
    setDesc(false);

    positions.current = isReduce
      ? {
          ...positions.current,
          first: calcPosition(first, true),
          prev: calcPosition(prev, true),
          curr: calcPosition(curr, true),
          next: calcPosition(next, true),
          last: calcPosition(last, true),
        }
      : {
          ...positions.current,
          first: calcPosition(first),
          prev: calcPosition(prev),
          curr: calcPosition(curr),
          next: calcPosition(next),
          last: calcPosition(last),
        };
  }, []);

  /**
   * 定时器
   * 为了避免每次渲染生成一个新的定时器 需要用callback'来缓存计时器
   * @param {*} isFirst
   */
  const handlerImagePosition = React.useCallback((isFirst) => {
    timer.current = setInterval(() => {
      changeImagePosition();
    }, 3000);
    if (isFirst) {
      changeImagePosition();
    }
  }, []);

  // position发生变化的时候需要将当前的图片文案显示
  // 需要通过监听positions的变化
  React.useEffect(() => {
    setTimeout(() => {
      setDesc(true);
    }, 500);
  }, [Desc]);

  // 默认计时器 只需要一次就行
  React.useEffect(() => {
    handlerImagePosition(true);
    return () => clearInterval(timer.current);
  }, []);

  // 移入事件
  const onMouseEnter = () => {
    clearInterval(timer.current);
    setshowButton(true);
  };

  // 移出事件
  const onMouseLeave = () => {
    handlerImagePosition();

    setshowButton(false);
  };

  const { curr, prev, next, first, last } = positions.current;
  return (
    <div
      className="carousel"
      onMouseEnter={onMouseEnter}
      onMouseLeave={onMouseLeave}
    >
      <div className="image_list">
        {imageList.map((item, index) => {
          return (
            <div
              key={index}
              // 通过currImage 与 index 比较当前应该展示的图片
              className={`image_wrap animat ${
                index === curr
                  ? "curr"
                  : index === prev
                  ? "prev"
                  : index === next
                  ? "next"
                  : index === first
                  ? "first"
                  : "last"
              }`}
            >
              {/* 通过showDesc来判断是否显示文案 */}
              <div
                className={`desc${index === curr && Desc ? " showDesc" : ""}`}
              >
                {item.desc}
              </div>
              <img src={item.src} alt="" />
            </div>
          );
        })}
      </div>
      <button
        onClick={() => changeImagePosition(true)}
        className={`changeBtn leftBtn${showButton ? " showButton" : ""}`}
      >
        {"<"}
      </button>
      <button
        onClick={() => changeImagePosition()}
        className={`changeBtn rightBtn${showButton ? " showButton" : ""}`}
      >
        {">"}
      </button>
    </div>
  );
}
